package start;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import proxyskeleton.VirtualHDProxy;
import jaxb.messages.Folder;
import jaxb.messages.Resource;
import virtualHD.VirtualHD;
import virtualHD.VirtualHDException;

public class StrongBoxClient implements VirtualHD{

	private String configFile = "./resources/AuthClient.config"; //default

	/**
	 * 
	 * @param serverHost ip address of remote service and kerberos kdc
	 * @param serverPort server port
	 * @param serviceName name of remote service in the form service@REALM
	 */
	public StrongBoxClient(String serverHost,int serverPort,String serviceName){
		this.serverHost = serverHost;
		this.serverPort = serverPort;
		this.serviceName = serviceName;

		System.setProperty("java.security.krb5.realm",serviceName.split("@")[1]);
		System.setProperty("java.security.krb5.kdc",serverHost);
		System.setProperty("java.security.auth.login.config",configFile);
	}



	/**
	 * @param args
	 * @throws IOException 
	 * @throws NumberFormatException 
	 */
	public static void main(String[] args) throws NumberFormatException, IOException {

		if(args.length != 3){
			System.err.println("Usage: StrongBoxClient <username> <password> <serverAddr>");
			System.exit(-1);
		}

		String userid = args[0];
		String password = args[1];
		String serverAddr = args[2];

		StrongBoxClient sbc = new StrongBoxClient(serverAddr,1234,"strongbox/linux@SECURITYHELL.IT");
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		int choice = 0;
		Folder folder = new Folder();
		Resource resource = new Resource();

		boolean opened = false;

		do{
			System.out.println("******************  STRONGBOX!! ***********************************\n");
			System.out.println("1. OpenHD");
			System.out.println("2. View");
			System.out.println("3. Put");
			System.out.println("4. Get");
			System.out.println("5. Del");
			System.out.println("6. Change permits");
			System.out.println("7. CloseHD");
			System.out.print(">");

			choice = Integer.parseInt(in.readLine());


			try{
				switch(choice){
				case 1:
					sbc.openHD(userid, password);
					System.out.println("Connection opened!");
					opened = true;
					break;
				case 2:
					if(opened){
						System.out.print("Folder>");
						folder.setUserid(in.readLine());
						Resource[] r = sbc.view(folder);
						System.out.println("=============================================================");
						System.out.println("Name \tLastMod \tSize(KB)");
						for(int i=0;i<r.length;i++){
							System.out.println(r[i].getName()+"\t"+r[i].getLastMod()+"\t"+
									(float)(r[i].getSize()/1024));
						}
						System.out.println("=============================================================");
					}else
						System.err.println("You have to open a connection before!");
					break;

				case 3:
					if(opened){
						System.out.print("Folder to put>");
						folder.setUserid(in.readLine());
						System.out.println("Resource name>");
						resource.setName(in.readLine());
						sbc.put(folder, resource);
						System.out.println("Uploaded!");
					}else
						System.err.println("You have to open a connection before!");
					break;

				case 4:
					if(opened){
						System.out.println("From folder>");
						folder.setUserid(in.readLine());
						System.out.println("Resource to get>");
						resource.setName(in.readLine());
						sbc.get(folder, resource);
						System.out.println("Downloaded!");
					}else
						System.err.println("You have to open a connection before!");
					break;

				case 5:
					if(opened){
						System.out.println("From folder>");
						folder.setUserid(in.readLine());
						System.out.println("Resource to del>");
						resource.setName(in.readLine());
						sbc.del(folder, resource);
						System.out.println("Resource deleted!");
					}else
						System.err.println("You have to open a connection before!");
					break;

				case 6:
					if(opened){
						System.out.println("User >");
						folder.setUserid(in.readLine());
						System.out.println("New role >");
						folder.setRole(in.readLine().toUpperCase());
						sbc.change_role(folder);
						System.out.println("Role changed!");
					}else
						System.err.println("You have to open a connection before!");

				case 7:
					if(opened){
						sbc.closeHD();
						System.out.println("Connection closed");
					}else
						System.err.println("You have to open a connection before!");
				default:
					System.out.println("Incorrect choice!");
				}

			}catch(VirtualHDException e){
				System.err.println(e.getMessage());
			}
		}while(choice != 7);

	}

	public void setConfigFile(String file){
		this.configFile = file;
		System.setProperty("java.security.auth.login.config","file:"+configFile);
	}

	@Override
	public void openHD(String userid, String password) throws VirtualHDException {
		if(virtualHD == null) //uninitialized
			virtualHD = new VirtualHDProxy(serverHost,serverPort,serviceName);
		this.username = userid;
		this.password = password;

		virtualHD.openHD(userid, password);
	}

	@Override
	public Resource[] view(Folder f) throws VirtualHDException {

		return virtualHD.view(f);
	}
	@Override
	public void put(Folder folder, Resource resource) throws VirtualHDException {
		virtualHD.put(folder, resource);
	}

	@Override
	public void get(Folder folder, Resource resource) throws VirtualHDException {
		virtualHD.get(folder, resource);

	}
	@Override
	public void del(Folder folder, Resource resource) throws VirtualHDException {
		virtualHD.del(folder, resource);
	}
	@Override
	public void change_role(Folder folder) throws VirtualHDException {
		virtualHD.change_role(folder);	
	}

	@Override
	public void closeHD() throws VirtualHDException {
		virtualHD.closeHD();
	}

	public String getUserID(){
		return this.username;
	}

	public String getPassword(){
		return this.password;
	}

	public String getService(){
		return this.serviceName;
	}

	public String getServerHost(){
		return this.serverHost;
	}

	public int getServerPort(){
		return this.serverPort;
	}

	private String username;
	private String password;

	private String serviceName;
	private String serverHost;
	private int serverPort;

	private VirtualHD virtualHD;

}
